#include "db/indexarray.hxx"
#include "db/iodatasegment.hxx"
#include "db/addressformat.hxx"
#include <iostream>
#include <stdlib.h>
#include <algorithm>
#include <vector>

void printHeader(DataSegmentHeader& h) {
    std::cout<<"Header: "<<std::endl;
    std::cout<<h.toString()<<std::endl;
}


DbStatus printData(IndexArrayFile& f, IODataSegment& seg) {
    
    DbStatus ret;

    int length = f.getHeader().getArrayLength();

    std::vector<uint64_t> v;
    for(int i = 0; i < length; ++i) {
        uint64_t addr = f.get(i);

        AddressFormat af(addr);
        uint16_t segID = af.getSegID();
        if(segID != seg.getSegId()) continue;
        v.push_back(addr);
    }

    std::sort(v.begin(), v.end());
    
    for(int i = 0; i < v.size(); ++i) {
       uint64_t addr = v[i];

       AddressFormat af(addr);
       uint16_t segID = af.getSegID();
       uint32_t offset = af.getOffset();
       uint32_t dataSize = af.getDataSize();

       std::string result;
       ret = seg.read(offset, dataSize, result);         
       if(!ret.isok()) return ret;

       std::cout<<"record "<<i<<":"<<std::endl;
       std::cout<<"length: "<<dataSize<<std::endl;
       std::cout<<"data: "<<result<<std::endl;
    }
}


void usage() {
    std::cout<<"indexarrayprint <partition path> <seg id>"<<std::endl;
    exit(-1);
}


int main(int argc, char** argv) {
    if(argc != 3) usage();

    std::string indexFile = std::string(argv[1]) + "/index.db";
    std::string segFile = std::string(argv[1]) + "/" + argv[2];
    uint16_t segID = atoi(argv[2]);

    DbStatus ret;
    IndexArrayFile f(indexFile);
    ret = f.init();
    if(!ret.isok()) return -1;    

    IODataSegment seg(segID, argv[1], 0);
    ret = seg.init(); if(!ret.isok()) return -1;

    IODataSegmentFile segf(segFile, NULL);
    ret = segf.init(); if(!ret.isok()) return -1;
    DataSegmentHeader h = segf.getHeader();
    printHeader(h);
   
    ret = printData(f, seg);
    if(!ret.isok()) std::cout<<ret.msg()<<std::endl;

    return 0;
}

